/*!
 * 文件名称： driver_can.c
 * 描    述： CAN 底层driver
 * 版本：     2023-12-03, V1.0
*/

/*
* GD32F303东方红开发板V1.0
* 淘宝商城：   https://juwo.taobao.com
* 技术交流：   https://www.gd32bbs.com/ask/
* 视频学习：   https://space.bilibili.com/475462605
* 微信公众号： gd32bbs
* Copyright    苏州聚沃电子科技有限公司
* 版权所有，盗版必究。
*/
#include "driver_public.h"
#include "driver_can.h"


/*!
* 说明     driver层CAN配置函数
* 输入	   typdef_can_general结构体
* 返回值   无
*/
void driver_can_config(typdef_can_general can_general)
{
		rcu_periph_clock_enable(can_general.rcu_can); //CAN时钟使能
    rcu_periph_clock_enable(can_general.rcu_IO_port); //IO时钟使能
		if(can_general.can_remap != 0) //如IO有remap，需要配置remap功能
		{
			rcu_periph_clock_enable(RCU_AF);
			gpio_pin_remap_config(can_general.can_remap,ENABLE);
		}   
    gpio_init(can_general.IO_port,GPIO_MODE_IPU,can_general.gpio_speed,can_general.pin_rx); //CAN RX IO配置
    gpio_init(can_general.IO_port,GPIO_MODE_AF_PP,can_general.gpio_speed,can_general.pin_tx); //CAN TX IO配置
	
    can_struct_para_init(CAN_INIT_STRUCT, &can_general.can_parameter); //CAN初始化结构体的初始化
    can_struct_para_init(CAN_INIT_STRUCT, &can_general.can_filter); //CAN过滤器结构体的初始化

    can_deinit(can_general.can_port); //CAN的deinit
    
    can_general.can_parameter.time_triggered = DISABLE;  //时间触发功能
    can_general.can_parameter.auto_bus_off_recovery = DISABLE;//busoff自恢复功能
    can_general.can_parameter.auto_wake_up = DISABLE; //自动唤醒功能
    can_general.can_parameter.no_auto_retrans = DISABLE;//自动重发功能，需要注意DISABLE为使能自动重发
    can_general.can_parameter.rec_fifo_overwrite = DISABLE;//接收溢出模式
    can_general.can_parameter.trans_fifo_order = DISABLE;//发送邮箱顺序配置
    can_general.can_parameter.working_mode = CAN_LOOPBACK_MODE;//回环模式
    can_general.can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;//再同步补偿
    can_general.can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;//BS1设置，注意这里设置为5，寄存器BS1[3:0]实际为4
    can_general.can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;//BS2设置，注意这里设置为4，寄存器BS2[2:0]实际为3
    
    /* 1MBps */
#if CAN_BAUDRATE == 1000 //波特率设置
    can_general.can_parameter.prescaler = 6;
    /* 500KBps */
#elif CAN_BAUDRATE == 500
    can_general.can_parameter.prescaler = 12;
    /* 250KBps */
#elif CAN_BAUDRATE == 250
    can_general.can_parameter.prescaler = 24;
    /* 125KBps */
#elif CAN_BAUDRATE == 125
    can_general.can_parameter.prescaler = 48;
    /* 100KBps */
#elif  CAN_BAUDRATE == 100
    can_general.can_parameter.prescaler = 60;
    /* 50KBps */
#elif  CAN_BAUDRATE == 50
    can_general.can_parameter.prescaler = 120;
    /* 20KBps */
#elif  CAN_BAUDRATE == 20
    can_general.can_parameter.prescaler = 300;
#else
    #error "please select list can baudrate in private defines in main.c "
#endif  
    /* initialize CAN */
    can_init(can_general.can_port, &can_general.can_parameter);//CAN初始化
    
    /* initialize filter */ 
    can_general.can_filter.filter_number=0; //过滤器号
    can_general.can_filter.filter_mode = CAN_FILTERMODE_MASK;//掩码模式
    can_general.can_filter.filter_bits = CAN_FILTERBITS_32BIT;//掩码位宽
    can_general.can_filter.filter_list_high = 0x3000<<1; //掩码和ID设置
    can_general.can_filter.filter_list_low = 0x0000;
    can_general.can_filter.filter_mask_high = 0x3000<<1;
    can_general.can_filter.filter_mask_low = 0x0000;
    can_general.can_filter.filter_fifo_number = CAN_FIFO0; //过滤器关联接收FIFO号
    can_general.can_filter.filter_enable = ENABLE; //过滤器使能    
    can_filter_init(&can_general.can_filter); //过滤器初始化
		
		can_general.can_filter.filter_number=1;
		can_general.can_filter.filter_list_high = 0x5000<<1;
    can_general.can_filter.filter_list_low = 0x0000;
    can_general.can_filter.filter_mask_high = 0x5000<<1;
    can_general.can_filter.filter_mask_low = 0x0000;
    can_general.can_filter.filter_fifo_number = CAN_FIFO1;
		
		can_filter_init(&can_general.can_filter);
		
		if(can_general.can_rx_use_interrupt == SET)//打开CAN接收中断
		{
			can_interrupt_enable(can_general.can_port, CAN_INT_RFNE0);
			can_interrupt_enable(can_general.can_port, CAN_INT_RFNE1);
		}
}

/*!
* 说明     driver层CAN发送函数
* 输入[1]  typdef_can_general结构体
* 输入[2]  can_trasnmit_message_struct结构体指针
* 返回值   无
*/
void driver_can_transmit(typdef_can_general can_general,can_trasnmit_message_struct *transmit_message)
{
	can_message_transmit(can_general.can_port,transmit_message);
}


